(*词法分析器lexer.mll，用ocamllex生成lexer.ml*)
{
  open Token
  exception Error of string   (*词法分析异常*)
}

(*常用字符：数字、字母、下划线、空白、换行符*)
let digit = ['0'-'9']
let alpha = ['a'-'z' 'A'-'Z' '_']
let id = alpha (alpha | digit )*
let space = [' ' '\t' '\r' '\n']
let newline = '\r' | '\n' | "\r\n"

(*词法分析规则*)
rule token = parse
  (*跳过空白、注释*)
  | space+    { token lexbuf }  
  | "//" [^ '\n' ]* { token lexbuf }  
  | "/*"            { comment lexbuf }  
  
  (* 关键字 *)
  | "int"          { INT }
  | "void"         { VOID }
  | "if"           { IF }
  | "else"         { ELSE }
  | "while"        { WHILE }
  | "break"        { BREAK }
  | "continue"     { CONTINUE }
  | "return"       { RETURN }
  
  (*标识符*)
  | id as id { ID id }
  
  (*整数，0单独处理*)
  | '-'? '0'       { NUM 0 }
  |'-'? ['1'-'9'] ('0'* ['1'-'9'])* as num { NUM (int_of_string num) }
  
  (*运算符和分隔符*)
  | '+'            { ADD }
  | '-'            { SUB }
  | '*'            { MUL }
  | '/'            { DIV }
  | '='            { ASSIGN }
  | ';'            { SEMICOLON }
  | ','            { COMMA }
  | '('            { LPAREN }
  | ')'            { RPAREN }
  | '{'            { LBRACE }
  | '}'            { RBRACE }
  | '%'            { MOD }
  | '!'            { NOT }
  | "&&"           { AND }
  | "||"           { OR }
  | '<'            { LT }
  | '>'            { GT }
  | "<="           { LE }
  | ">="           { GE }
  | "=="           { EQ }
  | "!="           { NE }
  | eof            { EOF }

  (*非法字符错误处理*)
  | _ as invalid_char           { 
      let error_message = Printf.sprintf "Illegal character: %c " invalid_char  in
      raise (Error error_message)
    }
    
(*多行注释*)
and comment = parse
  | "*/"       { token lexbuf }  
  | newline | _ { comment lexbuf }  
  | eof        { 
      raise (Error "Unterminated multi-line comment") 
    }